package com.hellogood.yaohuo.client.bussiness;

import java.util.Date;
import java.util.List;

import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.hellogood.yaohuo.client.common.BasicVoSearchInterface;
import com.hellogood.yaohuo.client.common.CodeRowEditorExitHandler;
import com.hellogood.yaohuo.client.common.LoginUser;
import com.hellogood.yaohuo.client.common.OrgCodeEditorExitHandler;
import com.hellogood.yaohuo.shared.data.Constants;
import com.hellogood.yaohuo.shared.entity.Color;
import com.hellogood.yaohuo.shared.entity.Detail;
import com.hellogood.yaohuo.shared.entity.Form;
import com.hellogood.yaohuo.shared.entity.Org;
import com.hellogood.yaohuo.shared.services.ColorService;
import com.hellogood.yaohuo.shared.services.CommonService;
import com.hellogood.yaohuo.shared.services.OrgService;
import com.hellogood.yaohuo.shared.vo.BasicVo;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.RightMouseDownEvent;
import com.smartgwt.client.widgets.events.RightMouseDownHandler;
import com.smartgwt.client.widgets.events.ShowContextMenuEvent;
import com.smartgwt.client.widgets.events.ShowContextMenuHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.DateItem;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextAreaItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.fields.events.BlurEvent;
import com.smartgwt.client.widgets.form.fields.events.BlurHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.Layout;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.menu.Menu;
import com.smartgwt.client.widgets.menu.MenuItem;
import com.smartgwt.client.widgets.menu.events.ClickHandler;
import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;

public abstract class FormController implements BasicVoSearchInterface {
	protected Record[] data = null;
	private DataSource ds = null;

	protected TextItem codeItem = null;
	protected SelectItem pszxItem = null;
	protected TextItem vendorItem = null;
	protected TextItem orgItem = null;
	protected DateItem dateItem = null;
	protected TextItem zdUserItem = null;
	protected TextItem remarkItem = null;
	protected TextAreaItem ziyouItem = null;

	protected Label titleLabel = null;
	protected ListGrid listGrid = null;
	protected DynamicForm form = null;
	protected DynamicForm ziyouForm = null;
	protected Layout layout = null;
	protected AbstractTab tab = null;
	protected int status;
	protected int row;
	protected int col;

	protected boolean canBeSave = true;

	private Menu itemListMenu = null;
	protected ListGridField colorField = new ListGridField("color", "颜色");

	protected VLayout printLayout = null;
	protected ListGrid printListGrid = null;
	protected DynamicForm printForm = null;

	protected boolean isCancelBtnClicked = false;

	protected HandlerRegistration exitCell = null;
	protected HandlerRegistration exitRow = null;
	protected HandlerRegistration blurOrg = null;
	protected HandlerRegistration blurVendor = null;
	protected HandlerRegistration blurPszx = null;

	protected Window msgWindow = null;

	public FormController(AbstractTab tab) {
		this.tab = tab;
		initView();
		initData();

		blurOrg = orgItem.addBlurHandler(new OrgBlurHandler());
		if (vendorItem != null) {
			blurVendor = vendorItem.addBlurHandler(new VendorBlurHandler());
		}
		if (pszxItem != null) {
			blurPszx = pszxItem.addBlurHandler(new PszxBlurHandler());
		}
		listGrid.addRightMouseDownHandler(new RightMouseDownHandler() {

			@Override
			public void onRightMouseDown(RightMouseDownEvent event) {
				Record r = listGrid.getSelectedRecord();
				if (r != null) {
					int index = listGrid.getRecordIndex(r);
					if (index >= 0) {
						setupContextMenu();
						itemListMenu.showContextMenu();
					}
				}
			}
		});

		listGrid.addShowContextMenuHandler(new ShowContextMenuHandler() {

			@Override
			public void onShowContextMenu(ShowContextMenuEvent event) {
				Record r = listGrid.getSelectedRecord();
				if (r != null) {
					int index = listGrid.getRecordIndex(r);
					if (index >= 0) {
						setupContextMenu();
						listGrid.setContextMenu(itemListMenu);
						itemListMenu.showContextMenu();
					}
				}
			}
		});
	}

	public void initData() {
		ColorService.Util.getInstance().getAllColorList(new ColorListAsyncCallback());
	}

	public abstract void initView();

	private class ColorListAsyncCallback implements AsyncCallback<List<Color>> {

		@Override
		public void onFailure(Throwable caught) {
			SC.say(caught.getMessage());
		}

		@Override
		public void onSuccess(List<Color> result) {
			if (result != null) {
				ds = new DataSource();
				DataSourceTextField idField = new DataSourceTextField("colorCode", "ColorCode");
				idField.setPrimaryKey(true);
				DataSourceTextField nameField = new DataSourceTextField("colorName", "分类名称");
				ds.setFields(idField, nameField);
				ds.setClientOnly(true);
				for (int i = 0; i < result.size(); i++) {
					ListGridRecord r = new ListGridRecord();
					Color c = result.get(i);
					r.setAttribute("color", c.getColorCode() + "-" + c.getColorName());
					if (c.getSuperCode().equals("0")) {
						r.setEnabled(false);
					}
					ds.addData(r);
				}
				if (colorField != null) {
					colorField.setOptionDataSource(ds);
				}
			}
		}
	}

	private class OrgByCodeAsynCallback implements AsyncCallback<Org> {

		@Override
		public void onFailure(Throwable caught) {
			SC.say(caught.getMessage());
		}

		@Override
		public void onSuccess(Org result) {
			if (result != null) {
				if (orgItem.getTitle().equals("配送中心")) {
					orgItem.setValue(result.getOrgCode() + "-" + result.getOrgName());
				} else if (vendorItem != null && vendorItem.getTitle().equals("配送中心")) {
					vendorItem.setValue(result.getOrgCode() + "-" + result.getOrgName());
				} else {
					if (pszxItem != null) {
						pszxItem.setValue(result.getOrgCode() + "-" + result.getOrgName());
					}
				}
			}
		}
	}

	public void initForm() {
		codeItem.setValue("*");
		orgItem.setValue("");
		orgItem.setDisabled(false);
		orgItem.setCanEdit(true);
		orgItem.focusInItem();
		codeItem.setDisabled(true);
		blurOrg = orgItem.addBlurHandler(new OrgBlurHandler());
		if (vendorItem != null) {
			blurVendor = vendorItem.addBlurHandler(new VendorBlurHandler());
		}
		dateItem.setDisabled(true);
		zdUserItem.setDisabled(true);
		OrgService.Util.getInstance().getOrgByCode(Constants.C001, new OrgByCodeAsynCallback());
		if (pszxItem != null) {
			pszxItem.setCanEdit(true);
			pszxItem.setDisabled(false);
			blurPszx = pszxItem.addBlurHandler(new PszxBlurHandler());
		}
		if (vendorItem != null) {
			vendorItem.setValue("");
			vendorItem.setCanEdit(true);
			vendorItem.setDisabled(false);
		}
		remarkItem.setValue("");
		remarkItem.setCanEdit(true);
		remarkItem.setDisabled(false);
		if (ziyouItem != null) {
			ziyouItem.setValue("");
			ziyouItem.setCanEdit(true);
			ziyouItem.setDisabled(false);
		}
		Date date = new Date();
		dateItem.setValue(date);
		zdUserItem.setValue(LoginUser.getInstance().getCurrentUser().getStaffCode() + "-" + LoginUser.getInstance().getCurrentUser().getStaffName());

		listGrid.setData(new Record[0]);
		status = Constants.FORM_STATUS_NEW;
		exitCell = listGrid.addEditorExitHandler(new OrgCodeEditorExitHandler(listGrid, this));
		exitRow = listGrid.addRowEditorExitHandler(new CodeRowEditorExitHandler(listGrid));
	}

	public void modifyForm() {
		listGrid.setDisabled(false);
		exitCell = listGrid.addEditorExitHandler(new OrgCodeEditorExitHandler(listGrid, this));
		exitRow = listGrid.addRowEditorExitHandler(new CodeRowEditorExitHandler(listGrid));
	}

	public void cancelForm() {
		isCancelBtnClicked = true;
/*		if (exitCell != null) {
			try {
				exitCell.removeHandler();
			} catch (AssertionError ae) {
				System.out.println(ae.getMessage());
			}
		}
		if (exitRow != null) {
			try {
				exitRow.removeHandler();
			} catch (AssertionError ae) {
				System.out.println(ae.getMessage());
			}
		}
*/		
		orgItem.setValue("-");
		// orgItem.blurItem();
		if (blurOrg != null) {
			orgItem.setRequired(false);
			try {
				blurOrg.removeHandler();
			} catch (AssertionError ae) {
				System.out.println(ae.getMessage());
			}
		}
		listGrid.cancelEditing();
		orgItem.setCanEdit(false);
		orgItem.setDisabled(true);
		orgItem.setValue("");
		dateItem.setValue("");
		zdUserItem.setValue("");
		if (pszxItem != null) {
			if (blurPszx != null) {
				pszxItem.setValue("-");
				// pszxItem.blurItem();
			}
			pszxItem.setValue("");
			pszxItem.setCanEdit(false);
			pszxItem.setDisabled(true);
		}
		if (vendorItem != null) {
			if (blurVendor != null) {
				vendorItem.setValue("-");
				// vendorItem.blurItem();
			}
			vendorItem.setDisabled(true);
			vendorItem.setValue("");
			vendorItem.setCanEdit(false);
		}
		remarkItem.setValue("");
		remarkItem.setDisabled(true);
		if (ziyouItem != null) {
			ziyouItem.setValue("");
			ziyouItem.setDisabled(true);
		}
		listGrid.cancelEditing();
		listGrid.discardAllEdits();

		listGrid.setData(new Record[0]);
	}

	public void deleteForm() {

		Object billNo = codeItem.getValue();
		if (billNo != null) {
			delete(billNo.toString());
		}

	}

	public abstract void delete(String billNo);

	public void updateForm(Form form) {
		codeItem.setValue(form.getBillNo());
		codeItem.setCanEdit(false);
		codeItem.setDisabled(true);
		if (form.getShopCode() != null) {
			pszxItem.setValue(form.getOrgCode() + "-" + form.getOrgName());
			pszxItem.setCanEdit(false);
			pszxItem.setDisabled(true);
			orgItem.setValue(form.getShopCode() + "-" + form.getShopName());
			orgItem.setCanEdit(false);
		} else {
			orgItem.setValue(form.getOrgCode() + "-" + form.getOrgName());
			orgItem.setCanEdit(false);
		}
		orgItem.setDisabled(true);

		if (form.getVendorCode() != null) {
			vendorItem.setValue(form.getVendorCode() + "-" + form.getVendorName());
			vendorItem.setCanEdit(false);
			vendorItem.setDisabled(true);
		}
		dateItem.setValue(form.getBillDate());
		dateItem.setCanEdit(false);
		dateItem.setDisabled(true);
		zdUserItem.setValue(form.getStaffCode() + "-" + form.getStaffName());
		zdUserItem.setCanEdit(false);
		zdUserItem.setDisabled(true);
		remarkItem.setValue(form.getRemark());
		remarkItem.setCanEdit(false);
		remarkItem.setDisabled(true);
		if (ziyouItem != null) {
			ziyouItem.setValue(form.getZiyou());
			ziyouItem.setCanEdit(false);
			ziyouItem.setDisabled(true);
		}
		List<Detail> list = form.getList();
		Record[] rds = new Record[list.size()];
		for (int i = 0; i < list.size(); i++) {
			Detail vo = list.get(i);
			Record r = new Record();
			r.setAttribute("pluCode", vo.getPluCode());
			r.setAttribute("barCode", vo.getBarCode());
			r.setAttribute("pluName", vo.getPluName());
			r.setAttribute("dept", vo.getDepCode() + "-" + vo.getDepName());
			r.setAttribute("type", vo.getClsCode() + "-" + vo.getClsName());
			r.setAttribute("unit", vo.getUnit());
			r.setAttribute("color", vo.getColor());
			r.setAttribute("size1", vo.getSize_s());
			r.setAttribute("size2", vo.getSize_m());
			r.setAttribute("size3", vo.getSize_l());
			r.setAttribute("size4", vo.getSize_xl());
			r.setAttribute("size5", vo.getSize_xxl());
			r.setAttribute("size6", vo.getSize_xxxl());
			r.setAttribute("size", vo.getSize_avg());
			r.setAttribute("amount", vo.getCounts());
			r.setAttribute("jPrice", vo.getjPrice());
			r.setAttribute("netJPrice", vo.getNetJPrice());
			r.setAttribute("cost", vo.getCost());
			r.setAttribute("netCost", vo.getNetCost());
			r.setAttribute("total", vo.getTotal());
			r.setAttribute("price", vo.getPrice());
			r.setAttribute("remark", vo.getRemark());
			r.setAttribute("psPrice", vo.getPsPrice());
			r.setAttribute("psCost", vo.getPsCost());
			r.setAttribute("counts", vo.getCounts());
			r.setAttribute("ziyou", vo.getZyCode() + "-" + vo.getZyName());
			rds[i] = r;
		}
		listGrid.setData(rds);
		FormItem[] items = this.form.getFields();
		if (items != null) {
			for (FormItem item : items) {
				item.setValue(item.getValue());
				item.focusInItem();
			}
		}
		if (form.getRzDate() != null && !form.getRzDate().equals("")) {
			if (items != null) {
				for (FormItem item : items) {
					item.setCanEdit(false);
				}
			}
			tab.showRzSuccessful();
			status = Constants.FORM_STATUS_BANKED;
		} else {
			tab.showSaveSuccessful();
			status = Constants.FORM_STATUS_SAVED;
		}
		exitCell = listGrid.addEditorExitHandler(new OrgCodeEditorExitHandler(listGrid, this));
		exitRow = listGrid.addRowEditorExitHandler(new CodeRowEditorExitHandler(listGrid));

		fillPrintForm(form);
		printListGrid.setData(rds);
	}

	protected abstract void saveForm();

	protected abstract String doSave(String billNo, boolean isModify);

	protected String save(String billNo, boolean isModify) {
		if (exitCell != null) {
			try {
				exitCell.removeHandler();
			} catch (AssertionError ae) {
				System.out.println(ae.getMessage());
			}
		}
		if (exitRow != null) {
			try {
				exitRow.removeHandler();
			} catch (AssertionError ae) {
				System.out.println(ae.getMessage());
			}
		}
		listGrid.cancelEditing();

		if (row != -1) {
			String pluCode = listGrid.getEditedCell(row, "pluCode") == null ? null : listGrid.getEditedCell(row, "pluCode").toString();
			Object org = orgItem.getValue();
			if (pluCode != null && org != null) {
				CommonService.Util.getInstance().getBasicVoByCodeAndOrgCode(pluCode, org.toString(), new CheckPlucodeCallback(billNo, isModify));
				return "";
			} else {
				return doSave(billNo, isModify);
			}
		} else {
			return doSave(billNo, isModify);
		}
	}

	abstract public void bankForm();

	public ListGrid getListGrid() {
		return listGrid;
	}

	public TextItem getOrgItem() {
		return orgItem;
	}

	public Canvas getCanvas() {
		return layout;
	}

	public DynamicForm getForm() {
		return form;
	}

	public int getStatus() {
		return status;
	}

	private void setupContextMenu() {
		itemListMenu = new Menu();
		itemListMenu.setCellHeight(22);
		itemListMenu.setWidth(100);

		final MenuItem delMenuItem = new MenuItem("删除");
		delMenuItem.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(MenuItemClickEvent event) {

				Record[] rds = listGrid.getSelectedRecords();
				if (rds.length > 0) {
					SC.ask("确认删除该行?", new BooleanCallback() {
						public void execute(Boolean value) {
							if (value != null && value) {

								Record[] rds = listGrid.getSelectedRecords();
								if (listGrid != null) {
									for (Record r : rds) {
										listGrid.removeData(r);
									}
								}
							}
						}
					});
				}

			}
		});
		itemListMenu.setData(delMenuItem);
	}

	public abstract VLayout buildFormPrintView();

	public void fillPrintForm(Form form) {

	}

	public Canvas getPrintView() {
		return printLayout;
	}

	public Label getTitleLabel() {
		return titleLabel;
	}

	public class OrgBlurHandler implements BlurHandler {

		@Override
		public void onBlur(BlurEvent event) {

			if (form.validate()) {
				listGrid.setData(new Record[0]);
				if (orgItem.getValue() != null && orgItem.getValue().toString().contains("-")) {
					data = new ListGridRecord[1];
					Record r = new ListGridRecord();
					data[0] = r;
					listGrid.setData(data);
				}
			}
		}
	}

	public class VendorBlurHandler implements BlurHandler {

		@Override
		public void onBlur(BlurEvent event) {

			if (form.validate()) {
				listGrid.setData(new Record[0]);
				if (vendorItem != null) {
					if (vendorItem.getValue() != null && vendorItem.getValue().toString().contains("-")) {
						data = new ListGridRecord[1];
						Record r = new ListGridRecord();
						data[0] = r;
						listGrid.setData(data);
					}
				}
			}
		}
	}

	protected class PszxBlurHandler implements BlurHandler {

		@Override
		public void onBlur(BlurEvent event) {

			if (form.validate()) {
				listGrid.setData(new Record[0]);
				if (pszxItem != null) {
					if (pszxItem.getValue() != null && pszxItem.getValue().toString().contains("-")) {
						data = new ListGridRecord[1];
						Record r = new ListGridRecord();
						data[0] = r;
						listGrid.setData(data);
					}
				}
			}
		}
	}

	protected class CheckPlucodeCallback implements AsyncCallback<BasicVo> {
		private String billNo;
		private boolean isModify;

		public CheckPlucodeCallback(String billNo, boolean isModify) {
			this.billNo = billNo;
			this.isModify = isModify;
		}

		@Override
		public void onFailure(Throwable caught) {
			SC.say(caught.getMessage());
		}

		@Override
		public void onSuccess(BasicVo result) {
			if (result != null) {
				doSave(billNo, isModify);
			} else {
				SC.say("编码 " + billNo + " 不存在");
				canBeSave = false;
				msgWindow.destroy();
			}
		}
	}
}
